home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / vgl20.zip / VGLFONTS.C < prev    next >
C/C++ Source or Header  |  1993-05-15  |  11KB  |  334 lines

  1. /*****************************************************************************
  2.  VGLFONTS.C
  3.  
  4.  Routines to add bitmapped font capabilities.  Read the comments for each
  5.  routine for instructions on how to use them.  They're pretty straight
  6.  forward.
  7.  
  8.  Mark
  9.  morley@camosun.bc.ca
  10. *****************************************************************************/
  11.  
  12. #include <stdio.h>
  13. #include <dos.h>
  14. #include <dir.h>
  15. #include "vgl.h"
  16.  
  17. static VGLFONT       header;            /* The current font info.           */
  18. static unsigned char buffer[4096];      /* All bitmaps for a font must fit  */
  19.                                         /* within this buffer.  This does   */
  20.                                         /* not include the header data, so  */
  21.                                         /* all the fonts I included with    */
  22.                                         /* this package will fit just fine. */
  23.  
  24. static int cx = 0;                      /* The current X and Y position of  */
  25. static int cy = 0;                      /* the invisible "cursor".  This is */
  26.                                         /* where the next character will be */
  27.                                         /* drawn.  X is the leftmost column */
  28.                                         /* of the character, but Y is *NOT* */
  29.                                         /* the topmost row!  Y is the row   */
  30.                                         /* that lines up with the char's    */
  31.                                         /* *BASELINE*                       */
  32.  
  33. static int color = 15;                  /* Default color for text is white  */
  34. static int shcolor = 1;                 /* Shadow color is blue             */
  35. static int uncolor = 1;                 /* Underline color is blue          */
  36. static int bold = 0;                    /* Bolding is off                   */
  37. static int shadow = 0;                  /* Shadows are off                  */
  38. static int italic = 0;                  /* Italics are off                  */
  39. static int underline = 0;               /* Underlining is off               */
  40.  
  41. /*****************************************************************************
  42.   Turns bolding off.
  43. *****************************************************************************/
  44. vglBoldOff()
  45. {
  46.    bold = 0;
  47.    return;
  48. }
  49.  
  50. /*****************************************************************************
  51.   Turns bolding on.
  52. *****************************************************************************/
  53. vglBoldOn()
  54. {
  55.    bold = 1;
  56.    return;
  57. }
  58.  
  59. /*****************************************************************************
  60.   Returns the current X position.  Remember that X represents the column that
  61.   will match the leftmost column of the next character.
  62. *****************************************************************************/
  63. vglGetX()
  64. {
  65.    return cx;
  66. }
  67.  
  68. /*****************************************************************************
  69.   Turns the current Y position.  Remember that Y represents the row that will
  70.   match the BASELINE of the next character!
  71. *****************************************************************************/
  72. vglGetY()
  73. {
  74.    return cy;
  75. }
  76.  
  77. /*****************************************************************************
  78.   Goto X,Y.  See the above two functions for an explanation of the X and Y
  79.   meanings.
  80. *****************************************************************************/
  81. vglGotoXY( int x, int y )
  82. {
  83.    cx = x;
  84.    cy = y;
  85.    if( cy < header.vspace )
  86.       cy = header.vspace;
  87.    return;
  88. }
  89.  
  90. /*****************************************************************************
  91.   Turns italics on.  I'm afraid my "italics" are not the nicest.  I simply
  92.   shear the character to the right, one pixel per scan line.  This is
  93.   perhaps a little *too* italicised.
  94. *****************************************************************************/
  95. vglItalicsOn()
  96. {
  97.    italic = 1;
  98.    return;
  99. }
  100.  
  101. /*****************************************************************************
  102.   Turns italics off.
  103. *****************************************************************************/
  104. vglItalicsOff()
  105. {
  106.    italic = 0;
  107.    return;
  108. }
  109.  
  110. /*****************************************************************************
  111.   Loads a font from disk.  If the font can be read it returns 1, else it
  112.   returns 0.  Only one font can be in memory at a time, but since fonts are
  113.   generally small due to the font file format, you can load them pretty
  114.   quickly.
  115. *****************************************************************************/
  116. vglLoadFont( char* font )
  117. {
  118.    FILE* fp;
  119.  
  120.    fp = fopen( font, "rb" );
  121.    if( !fp )
  122.       return 0;
  123.    fread( &header, sizeof(VGLFONT), 1, fp );
  124.    fread( buffer, header.data, 1, fp );
  125.    fclose( fp );
  126.    return 1;
  127. }
  128.  
  129. /*****************************************************************************
  130.   The kernel of the font engine.  Messy Marvin time.  Oh well, whaddya expect
  131.   for a 2 hour hack?  Anyway, this is the routine that actually draws a
  132.   character on the screen at the current X,Y location.  It advances the X,Y
  133.   position and wraps across and down the screen as necessary.  At the end of
  134.   the screen it will wrap back to the top left corner.  If you try and
  135.   display a carriage return or newline, they will work just like they would
  136.   in a printf() call.
  137.  
  138.   The routine works by drawing the character into a tiny buffer, then calling
  139.   the vglPutSprite() routine to display it.  This means that you cannot use
  140.   the color 0 for text, underlines, or shadows because it will be transparent.
  141.   If you want black shadows, use another palette entry!
  142.  
  143.   This routine, along with the font file format, was created in about 2
  144.   hours.  I HAVEN'T FULLY TESTED IT!!!  It works for me (so far), and
  145.   hopefully you will find it useful.
  146.  
  147.   WARNING: This ain't no speed demon!  I was more interested in having a
  148.   small font file format.  I also wanted the font to take up minimal RAM
  149.   when loaded.  These means more processing.
  150.  
  151.   I hope to add other text effects (eg: outline), but who knows?
  152. *****************************************************************************/
  153. vglPutc( int c )
  154. {
  155.    register       x, y;
  156.    int            bit, oy;
  157.    unsigned char* off;
  158.    unsigned char  rast[2048];
  159.    unsigned char* b;
  160.    int            h, w, rw, o, oo;
  161.    int            wid, hit;
  162.  
  163.    if( header.flags & FONT_UPPERCASE && c >= 'a' && c <= 'z' )
  164.       c -= 32;
  165.    if( c < 33 )
  166.    {
  167.       switch( c )
  168.       {
  169.          case '\r'      : cx = 0;
  170.                           break;
  171.          case '\n'      : cy += header.vspace;
  172.                           break;
  173.          case ' '       : if( underline )
  174.                           {
  175.                              for( y = 1; y <= underline; y++ )
  176.                                 vglLine( cx, cy + y, cx + header.wswid, cy + y, uncolor );
  177.                           }
  178.                           cx += header.wswid;
  179.                           break;
  180.       }
  181.       return;
  182.    }
  183.    if( header.chwid[c] == 0 )
  184.       return;
  185.    h = header.chhit[c];
  186.    w = header.chwid[c];
  187.    if( italic )
  188.       oo = h / 2;
  189.    else
  190.       oo = 0;
  191.    o = oo;
  192.    rw = w + bold + shadow + o;
  193.    if( cx + rw > 319 )
  194.    {
  195.       cx = 0;
  196.       cy += header.vspace;
  197.    }
  198.    if( cy > 199 )
  199.    {
  200.       cx = 0;
  201.       cy = header.vspace;
  202.    }
  203.    off = buffer + header.choff[c];
  204.    oy = cy - header.chbas[c] + 1;
  205.    memset( rast, 0, 2048 );
  206.    b = rast;
  207.    wid = rw;
  208.    hit = h + shadow;
  209.    if( underline )
  210.    {
  211.       for( y = 1; y <= underline; y++ )
  212.          vglLine( cx, cy + y, cx + rw + header.hspace, cy + y, uncolor );
  213.    }
  214.    for( y = 0; y < h; y++ )
  215.    {
  216.       bit = 1;
  217.       b += o;
  218.       for( x = 0; x < w; x++, bit <<= 1 )
  219.       {
  220.          if( bit == 256 )
  221.          {
  222.             bit = 1;
  223.             off++;
  224.          }
  225.          if( *off & bit )
  226.          {
  227.             *b = color;
  228.             if( shadow )
  229.                *(b + shadow + rw * shadow) = shcolor;
  230.             if( bold )
  231.             {
  232.                *(b + 1) = color;
  233.                if( shadow )
  234.                   *(b + 1 + shadow + rw * shadow) = shcolor;
  235.             }
  236.          }
  237.          b++;
  238.       }
  239.       b += bold + shadow + (oo - o);
  240.       if( italic && (y & 1) )
  241.          o--;
  242.       off++;
  243.    }
  244.    vglPutSprite( cx, oy, wid, hit, (char far*)rast );
  245.    cx += w + bold;
  246.    cx += header.hspace;
  247.    return;
  248. }
  249.  
  250. /*****************************************************************************
  251.   Displays a string.  To display a formatted string (like printf) you should
  252.   first use sprintf to print into a buffer, then pass that buffer to vglPuts
  253. *****************************************************************************/
  254. vglPuts( char* s )
  255. {
  256.    while( *s )
  257.       vglPutc( *s++ );
  258.    return;
  259. }
  260.  
  261. /*****************************************************************************
  262.   Sets the shadow color.  This does *not* turn shadows on!
  263. *****************************************************************************/
  264. vglShadowColor( int c )
  265. {
  266.    shcolor = c;
  267.    return;
  268. }
  269.  
  270. /*****************************************************************************
  271.   Turns shadows off.
  272. *****************************************************************************/
  273. vglShadowOff()
  274. {
  275.    shadow = 0;
  276.    return;
  277. }
  278.  
  279. /*****************************************************************************
  280.   Turns shadows on.  The "depth" of the shadow is specified in pixels.
  281.   Normally a value of 1 or 2 looks good.
  282. *****************************************************************************/
  283. vglShadowOn( int s )
  284. {
  285.    if( s > 10 )
  286.       s = 10;
  287.    else if( s < 1 )
  288.       s = 1;
  289.    shadow = s;
  290.    return;
  291. }
  292.  
  293. /*****************************************************************************
  294.   Sets the text color.
  295. *****************************************************************************/
  296. vglTextColor( int c )
  297. {
  298.    color = c;
  299.    return;
  300. }
  301.  
  302. /*****************************************************************************
  303.   Sets the underline color.
  304. *****************************************************************************/
  305. vglUnderlineColor( int c )
  306. {
  307.    uncolor = c;
  308.    return;
  309. }
  310.  
  311. /*****************************************************************************
  312.   Turns on underlining.  The thickness of the underlining is specified in
  313.   pixels.  A value of 1 or 2 usually looks good.
  314. *****************************************************************************/
  315. vglUnderlineOn( int n )
  316. {
  317.    if( n > 10 )
  318.       n = 10;
  319.    else if( n < 1 )
  320.       n = 1;
  321.    underline = n;
  322.    return;
  323. }
  324.  
  325. /*****************************************************************************
  326.   Turns off underlining.
  327. *****************************************************************************/
  328. vglUnderlineOff()
  329. {
  330.    underline = 0;
  331.    return;
  332. }
  333.  
  334.